"""
日志工具模块
提供统一的日志记录功能
"""
import os
import logging
import logging.handlers
from datetime import datetime
from functools import wraps
from typing import Dict, Any, Optional

from flask import request, current_app, g

def setup_logging(app):
    """
    设置日志配置
    
    Args:
        app: Flask应用实例
    """
    # 创建日志目录
    log_dir = app.config.get('LOG_DIR', 'logs')
    os.makedirs(log_dir, exist_ok=True)
    
    # 配置日志格式
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s '
        '[in %(pathname)s:%(lineno)d]'
    )
    
    # 文件处理器 - 所有日志
    file_handler = logging.handlers.RotatingFileHandler(
        filename=os.path.join(log_dir, 'stehub.log'),
        maxBytes=10 * 1024 * 1024,  # 10MB
        backupCount=10,
        encoding='utf-8'
    )
    file_handler.setFormatter(formatter)
    file_handler.setLevel(logging.INFO)
    
    # 错误日志处理器
    error_handler = logging.handlers.RotatingFileHandler(
        filename=os.path.join(log_dir, 'error.log'),
        maxBytes=10 * 1024 * 1024,
        backupCount=5,
        encoding='utf-8'
    )
    error_handler.setFormatter(formatter)
    error_handler.setLevel(logging.ERROR)
    
    # 访问日志处理器
    access_handler = logging.handlers.RotatingFileHandler(
        filename=os.path.join(log_dir, 'access.log'),
        maxBytes=10 * 1024 * 1024,
        backupCount=5,
        encoding='utf-8'
    )
    access_handler.setFormatter(formatter)
    access_handler.setLevel(logging.INFO)
    
    # 安全日志处理器
    security_handler = logging.handlers.RotatingFileHandler(
        filename=os.path.join(log_dir, 'security.log'),
        maxBytes=5 * 1024 * 1024,
        backupCount=3,
        encoding='utf-8'
    )
    security_handler.setFormatter(formatter)
    security_handler.setLevel(logging.WARNING)
    
    # 设置根日志记录器
    root_logger = logging.getLogger()
    root_logger.setLevel(logging.INFO)
    
    # 清除已有的处理器
    for handler in root_logger.handlers[:]:
        root_logger.removeHandler(handler)
    
    # 添加处理器
    root_logger.addHandler(file_handler)
    root_logger.addHandler(error_handler)
    
    # 创建各个模块的日志记录器
    app_logger = logging.getLogger('stehub.app')
    app_logger.addHandler(file_handler)
    app_logger.addHandler(error_handler)
    
    access_logger = logging.getLogger('stehub.access')
    access_logger.addHandler(access_handler)
    
    security_logger = logging.getLogger('stehub.security')
    security_logger.addHandler(security_handler)
    
    # 在开发环境中添加控制台输出
    if app.debug:
        console_handler = logging.StreamHandler()
        console_handler.setFormatter(formatter)
        console_handler.setLevel(logging.DEBUG)
        root_logger.addHandler(console_handler)
        app_logger.addHandler(console_handler)

def get_logger(name: str = 'stehub.app') -> logging.Logger:
    """
    获取日志记录器
    
    Args:
        name: 记录器名称
        
    Returns:
        logging.Logger: 日志记录器实例
    """
    return logging.getLogger(name)

def log_request():
    """
    记录请求日志
    """
    if not hasattr(g, 'request_start_time'):
        g.request_start_time = datetime.utcnow()
    
    logger = get_logger('stehub.access')
    
    log_data = {
        'method': request.method,
        'path': request.path,
        'ip': request.remote_addr,
        'user_agent': request.user_agent.string,
        'referrer': request.referrer,
        'content_type': request.content_type,
        'content_length': request.content_length
    }
    
    # 记录敏感信息时要小心
    if request.method in ['POST', 'PUT', 'PATCH']:
        if request.content_type and 'application/json' in request.content_type:
            try:
                # 只记录非敏感字段
                data = request.get_json() or {}
                filtered_data = _filter_sensitive_data(data)
                log_data['request_data'] = filtered_data
            except Exception:
                log_data['request_data'] = '<unparseable>'
    
    logger.info("请求开始", extra=log_data)

def log_response(response):
    """
    记录响应日志
    
    Args:
        response: Flask响应对象
        
    Returns:
        Response: 原响应对象
    """
    if not hasattr(g, 'request_start_time'):
        return response
    
    # 计算请求处理时间
    processing_time = (datetime.utcnow() - g.request_start_time).total_seconds()
    
    logger = get_logger('stehub.access')
    
    log_data = {
        'method': request.method,
        'path': request.path,
        'status_code': response.status_code,
        'processing_time': processing_time,
        'content_length': response.content_length,
        'content_type': response.content_type
    }
    
    level = logging.INFO
    if response.status_code >= 400:
        level = logging.WARNING
    if response.status_code >= 500:
        level = logging.ERROR
    
    logger.log(level, "请求完成", extra=log_data)
    
    return response

def log_error(error: Exception, context: Dict[str, Any] = None):
    """
    记录错误日志
    
    Args:
        error: 异常对象
        context: 上下文信息
    """
    logger = get_logger('stehub.app')
    
    log_data = {
        'error_type': type(error).__name__,
        'error_message': str(error),
        'path': request.path if request else None,
        'method': request.method if request else None,
        'ip': request.remote_addr if request else None
    }
    
    if context:
        log_data.update(context)
    
    logger.error("应用程序错误", extra=log_data, exc_info=True)

def log_security_event(event_type: str, message: str, 
                      user_id: Optional[int] = None,
                      details: Dict[str, Any] = None):
    """
    记录安全事件
    
    Args:
        event_type: 事件类型
        message: 事件消息
        user_id: 用户ID
        details: 详细信息
    """
    logger = get_logger('stehub.security')
    
    log_data = {
        'event_type': event_type,
        'message': message,
        'user_id': user_id,
        'ip': request.remote_addr if request else None,
        'user_agent': request.user_agent.string if request else None,
        'timestamp': datetime.utcnow().isoformat()
    }
    
    if details:
        log_data.update(details)
    
    logger.warning("安全事件", extra=log_data)

def log_user_activity(activity: str, user_id: int, 
                     details: Dict[str, Any] = None):
    """
    记录用户活动
    
    Args:
        activity: 活动描述
        user_id: 用户ID
        details: 详细信息
    """
    logger = get_logger('stehub.app')
    
    log_data = {
        'activity': activity,
        'user_id': user_id,
        'ip': request.remote_addr if request else None,
        'timestamp': datetime.utcnow().isoformat()
    }
    
    if details:
        log_data.update(details)
    
    logger.info("用户活动", extra=log_data)

def log_database_operation(operation: str, model: str, 
                          record_id: Optional[int] = None,
                          details: Dict[str, Any] = None):
    """
    记录数据库操作
    
    Args:
        operation: 操作类型（create, read, update, delete）
        model: 模型名称
        record_id: 记录ID
        details: 详细信息
    """
    logger = get_logger('stehub.app')
    
    log_data = {
        'operation': operation,
        'model': model,
        'record_id': record_id,
        'user_id': getattr(g, 'user_id', None),
        'timestamp': datetime.utcnow().isoformat()
    }
    
    if details:
        log_data.update(details)
    
    logger.debug("数据库操作", extra=log_data)

def log_performance_metric(metric_name: str, value: float, 
                          unit: str = 'ms',
                          tags: Dict[str, str] = None):
    """
    记录性能指标
    
    Args:
        metric_name: 指标名称
        value: 指标值
        unit: 单位
        tags: 标签
    """
    logger = get_logger('stehub.app')
    
    log_data = {
        'metric': metric_name,
        'value': value,
        'unit': unit,
        'timestamp': datetime.utcnow().isoformat()
    }
    
    if tags:
        log_data.update(tags)
    
    logger.info("性能指标", extra=log_data)

def _filter_sensitive_data(data: Dict[str, Any]) -> Dict[str, Any]:
    """
    过滤敏感数据
    
    Args:
        data: 原始数据
        
    Returns:
        dict: 过滤后的数据
    """
    if not isinstance(data, dict):
        return data
    
    sensitive_fields = {
        'password', 'token', 'secret', 'key', 'authorization',
        'credit_card', 'cvv', 'ssn', 'phone', 'email'
    }
    
    filtered_data = {}
    for key, value in data.items():
        key_lower = key.lower()
        is_sensitive = any(sensitive in key_lower for sensitive in sensitive_fields)
        
        if is_sensitive:
            filtered_data[key] = '<filtered>'
        elif isinstance(value, dict):
            filtered_data[key] = _filter_sensitive_data(value)
        elif isinstance(value, list):
            filtered_data[key] = [
                _filter_sensitive_data(item) if isinstance(item, dict) else item
                for item in value
            ]
        else:
            filtered_data[key] = value
    
    return filtered_data

def log_decorator(logger_name: str = 'stehub.app'):
    """
    日志装饰器
    
    Args:
        logger_name: 日志记录器名称
        
    Returns:
        function: 装饰器函数
    """
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            logger = get_logger(logger_name)
            
            logger.debug(f"函数调用: {func.__name__}", extra={
                'args': str(args),
                'kwargs': str(kwargs)
            })
            
            try:
                result = func(*args, **kwargs)
                logger.debug(f"函数完成: {func.__name__}")
                return result
            except Exception as e:
                logger.error(f"函数错误: {func.__name__}", extra={
                    'error': str(e)
                }, exc_info=True)
                raise
        
        return wrapper
    return decorator